﻿// TypeFace.cs
//
// Author: Luoyingliang
// Email: 731984870@qq.com
// 
// Copyright (c) 2018 Team Acoris
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Text
{
    using static Acoris.Utils.ValueRangeChecker;
    using Acoris.Rendering;

    /// <summary>
    /// represents a type face
    /// </summary>
    public sealed class TypeFace:IEquatable<TypeFace>,IEqualityComparer<TypeFace>
    {
        public TypeFace(string fontFamily) {

            CheckEmptyString(fontFamily);
            CheckWhiteSpaceString(fontFamily);

            this.FontFamily = fontFamily;
        }

        /// <summary>
        /// gets or sets font family
        /// </summary>
        public string FontFamily { get; set; }

        /// <summary>
        /// gets or sets font weight
        /// </summary>
        public uint FontWeight { get; set; } = 400;

        /// <summary>
        /// gets or sets font size
        /// </summary>
        public float FontSize { get; set; } = 15f;

        /// <summary>
        /// gets or sets underline style
        /// </summary>
        //public UnderlineStyle UnderlineStyle { get; set; }

        /// <summary>
        /// gets or sets font style
        /// </summary>
        public int FontStyle { get; set; } = 400;        

        /// <summary>
        /// gets or sets a value which indicate tab stop increament
        /// </summary>
        public float TabIncreament { get; set; } = 4f;

        /// <summary>
        /// 
        /// </summary>
        public static TypeFace Default { get; private set; } = new TypeFace("Microsoft Yahei")
        {
            
        };

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        bool IEqualityComparer<TypeFace>.Equals(TypeFace x, TypeFace y) {
            return x.FontFamily == y.FontFamily &&
                   x.FontSize == y.FontSize &&
                   x.FontWeight == y.FontWeight &&
                   x.TabIncreament == y.TabIncreament &&
                   /*x.UnderlineStyle == y.UnderlineStyle && */
                   x.FontStyle == y.FontStyle;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        bool IEquatable<TypeFace>.Equals(TypeFace y) {
            var x = this;
            return x.FontFamily == y.FontFamily &&
                   x.FontSize == y.FontSize &&
                   x.FontWeight == y.FontWeight &&
                   x.TabIncreament == y.TabIncreament &&
                   /*x.UnderlineStyle == y.UnderlineStyle && */
                   x.FontStyle == y.FontStyle;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        int IEqualityComparer<TypeFace>.GetHashCode(TypeFace obj) {
            return obj.GetHashCode();
        }

        /// <summary>
        /// gets a value which indicate the specific object wheter equal current typeface
        /// </summary>
        /// <param name="obj">specific object</param>
        /// <returns>return a value which indicate the specific object wheter equal current typeface</returns>
        public override bool Equals(object obj) {
            if(obj is TypeFace tf) {
                return tf.FontFamily == this.FontFamily &&
                       tf.FontSize == this.FontSize &&
                       tf.FontWeight == this.FontWeight &&
                       tf.TabIncreament == this.TabIncreament &&
                       /*x.UnderlineStyle == y.UnderlineStyle && */
                       tf.FontStyle == this.FontStyle;
            }
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode() {
            return (base.GetHashCode() ^ FontFamily.GetHashCode()) + (int)FontSize;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString() {
            return FontFamily;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static bool operator !=(TypeFace x,TypeFace y) {
            return !(x.Equals(y));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static bool operator ==(TypeFace x,TypeFace y) {
            return x.Equals(y);
        }
    }
}
